package com.luobd.bpm.command;

import cn.hutool.core.util.StrUtil;
import com.luobd.bpm.activiti.CustomProcessInstanceHelper;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.ActivitiObjectNotFoundException;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.impl.cmd.StartProcessInstanceCmd;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.deploy.DeploymentManager;
import org.activiti.engine.impl.util.ProcessInstanceHelper;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;

import java.util.Map;

public class CustomStartProcessInstanceCmd <T> extends StartProcessInstanceCmd<T> {



    protected String processInstanceId;




    public CustomStartProcessInstanceCmd(String processDefinitionKey, String processDefinitionId,
                                         String businessKey, Map<String, Object> variables,String processInstanceId,String tenantId,String processName) {
        super(processDefinitionKey, processDefinitionId, businessKey, variables,tenantId);
        this.processInstanceId = processInstanceId;
        this.processInstanceName = processName;
    }

    @Override
    public ProcessInstance execute(CommandContext commandContext) {

        ProcessDefinition processDefinition = findProcessDefinition(commandContext);

        ProcessInstanceHelper instanceHelper = commandContext.getProcessEngineConfiguration().getProcessInstanceHelper();

        return findProcessInstance(instanceHelper, processDefinition);
    }


    protected ProcessDefinition findProcessDefinition(CommandContext commandContext) {
        DeploymentManager deploymentManager = commandContext.getProcessEngineConfiguration().getDeploymentManager();
        if(StrUtil.isNotBlank(processDefinitionId)) {
            ProcessDefinition definition = deploymentManager.findDeployedProcessDefinitionById(processDefinitionId);
            if(definition == null) {
                throw new ActivitiObjectNotFoundException("编号为:" + processDefinitionId + "的流程定义不存在");
            }
            return definition;
        }else if(StrUtil.isNotBlank(processDefinitionKey) &&
                (StrUtil.isBlank(tenantId) || ProcessEngineConfiguration.NO_TENANT_ID.equals(tenantId))) {
            ProcessDefinition definition = deploymentManager.findDeployedLatestProcessDefinitionByKey(processDefinitionKey);
            if(definition == null) {
                throw new ActivitiObjectNotFoundException("流程定义Key为:" + processDefinitionKey + "的流程定义不存在");
            }
            return definition;
        } else if (StrUtil.isNotBlank(processDefinitionKey) && StrUtil.isNotBlank(tenantId)) {
            ProcessDefinition definition = deploymentManager.findDeployedLatestProcessDefinitionByKeyAndTenantId(processDefinitionKey, tenantId);
            if(definition == null) {
                throw new ActivitiObjectNotFoundException("流程定义Key为:" + processDefinitionKey + "租户id为: " + tenantId + "的流程定义不存在");
            }
            return definition;
        }else {
            throw new ActivitiIllegalArgumentException("processDefinitionKey和processDefinitionId不能同时为空");
        }

    }

    protected ProcessInstance findProcessInstance(ProcessInstanceHelper instanceHelper,ProcessDefinition processDefinition) {
        if(StrUtil.isNotBlank(processInstanceId)) {
           return  ((CustomProcessInstanceHelper)instanceHelper).
                    createAndStartProcessInstance(processInstanceId,processDefinition,
                            businessKey, processInstanceName, variables, transientVariables, true);
        } else {
            return this.createAndStartProcessInstance(processDefinition,businessKey,processInstanceName,variables,transientVariables);
        }
    }




}
